home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / What's New? / Development Kits / Apple Game Sprockets DR1 / Examples / DroneZone / DZDisplay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-24  |  18.1 KB  |  638 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    File:        DZDisplay.c
  3.  *    Author:        Dan Venolia
  4.  *
  5.  *    Contents:    Handles the window and its contents.
  6.  *
  7.  *    Copyright © 1996 Apple Computer, Inc.
  8.  */
  9.  
  10. #ifndef USE_DRAW_SPROCKET
  11.     #define USE_DRAW_SPROCKET        1
  12. #endif
  13.  
  14. #include <assert.h>
  15.  
  16. #include <Windows.h>
  17.  
  18. #include <QD3D.h>
  19. #include <QD3DCamera.h>
  20. #include <QD3DDrawContext.h>
  21. #include <QD3DGroup.h>
  22. #include <QD3DLight.h>
  23. #include <QD3DMath.h>
  24. #include <QD3DRenderer.h>
  25. #include <QD3DShader.h>
  26. #include <QD3DView.h>
  27.  
  28. #include "DZDisplay.h"
  29. #include "DZGame.h"
  30. #include "DZResource.h"
  31.  
  32. #if USE_DRAW_SPROCKET
  33.     #include "DrawSprocket.h"
  34. #endif
  35.  
  36.  
  37. #if USE_DRAW_SPROCKET
  38.     static DisplayObject    gDisplayObject                = NULL;
  39. #else
  40.     static WindowPtr        gDisplayWindow                = NULL;
  41. #endif
  42.  
  43. static Boolean                gDisplayActive                = false;
  44.  
  45. static TQ3ViewObject        gDisplayView                = NULL;
  46. static TQ3DrawContextObject    gDisplayDrawContext            = NULL;
  47. static TQ3RendererObject    gDisplayRenderer            = NULL;
  48. static TQ3CameraObject        gDisplayCamera                = NULL;
  49. static TQ3GroupObject        gDisplayLightGroup            = NULL;
  50. static TQ3LightObject        gDisplayAmbientLight        = NULL;
  51. static TQ3LightObject        gDisplayDirectionalLight    = NULL;
  52. static TQ3LightObject        gDisplayPointLight            = NULL;
  53. static TQ3ShaderObject        gDisplayIllumination        = NULL;
  54.  
  55. //• To get around an Interactive Renderer bug wherein Q3Renderer_Sync
  56. //•    crashes when called on a renderer that has not rendered.
  57. static Boolean                gDisplayHasRendered            = false;
  58.  
  59.  
  60. #if USE_DRAW_SPROCKET
  61.     static Boolean Display_IsBusy(
  62.         DisplayObject        inDisplayObject,
  63.         UInt32                inContext);
  64. #endif
  65.  
  66. static void Display_GetImageArea(
  67.     TQ3Area*                outArea);
  68.  
  69. static float Display_GetImageAspectRatio(
  70.     void);
  71.  
  72.  
  73. /* =============================================================================
  74.  *        Display_Init (external)
  75.  *
  76.  *    Creates the display window, initializes QD3D view etc. to draw in it.
  77.  * ========================================================================== */
  78. void Display_Init(
  79.     void)
  80. {
  81.     TQ3ViewAngleAspectCameraData    viewAngleCameraData;
  82.     TQ3PointLightData                pointLightData;
  83.     TQ3ColorRGB                        white = {1.0, 1.0, 1.0};
  84.     
  85.     // uncomment the next line and draw sprocket won't make your life miserable when you drop into the debugger
  86.     // LeaveDisplaysVisible( false );
  87.     
  88.     // Create the view
  89.     gDisplayView = Q3View_New();
  90.     
  91.     // Set up where to draw
  92.     #if USE_DRAW_SPROCKET
  93.     {
  94.         DisplayConfig                    theConfig;
  95.         DisplayConfig                    theActualConfig;
  96.         
  97.         // Create the display
  98.         theConfig.device                    = NULL;
  99.         theConfig.mode                        = 0;
  100.         theConfig.frequency                    = 0;
  101.         theConfig.width                        = 512;
  102.         theConfig.height                    = 384;
  103.         theConfig.colorNeeds                = kDisplayColorRequest;
  104.         theConfig.colorTable                = NULL;
  105.         theConfig.specialFlags                 = kDisplaySpecialBuffered | kDisplaySpecialQD3DAccel;
  106.         theConfig.specialFlagsInHW             = 0;
  107.         theConfig.frontBufferDepthMask        = kDisplayDepthMaskAll;
  108.         theConfig.backBufferDepthMask        = kDisplayDepthMask32 | kDisplayDepthMask16;
  109.         theConfig.frontBufferBestDepth        = 32;
  110.         theConfig.backBufferBestDepth        = 32;
  111.         theConfig.pageCount                    = 2;
  112.         theConfig.reserved1                    = 0;    
  113.         theConfig.reserved2                    = 0;    
  114.         FindGDeviceFromConfig( &theConfig );
  115.         NewDisplay( &theConfig, &gDisplayObject );
  116.         
  117.         GetDisplayActualConfig( gDisplayObject, &theActualConfig );
  118.         if (theActualConfig.frontBufferBestDepth < 16)
  119.         {
  120.             //• SHOULD PUT UP AN ALERT HERE SAYING SOMETHING LIKE
  121.             //•    "The best monitor setting that DroneZone could find was XXX."
  122.             //• "DroneZone runs much faster in Thousands or Millions of Colors."
  123.             //• "You can run in Thousands or Millions of Colors if you expand"
  124.             //• "the Video RAM on your display card, or if you switch to a smaller"
  125.             //• "video monitor."  (OK) (Quit)
  126.         }
  127.         
  128.         // DSp_SetDebugMode( true );
  129.         
  130.         FadeDisplayGamma( NULL, kSmoothFadeOut, NULL );
  131.         SetDisplayPlayState( gDisplayObject, kDisplayPlayStateActive );
  132.         //• SHOW SPLASH SCREEN HERE
  133.         FadeDisplayGamma( NULL, kSmoothFadeIn, NULL );
  134.         
  135.         #if 1
  136.         {
  137.             GWorldPtr                        theGWorld;
  138.             PixMapHandle                    pixMapHandle;
  139.             TQ3PixmapDrawContextData        pixmapDrawContextData;
  140.             // Create the draw context
  141.             GetDisplayBackBuffer( gDisplayObject, &theGWorld );
  142.             pixMapHandle = GetGWorldPixMap(theGWorld);
  143.             
  144.             pixmapDrawContextData.drawContextData.clearImageMethod    = kQ3ClearMethodWithColor;
  145.             pixmapDrawContextData.drawContextData.clearImageColor.a    = 1.0;
  146.             pixmapDrawContextData.drawContextData.clearImageColor.r    = 0.0;
  147.             pixmapDrawContextData.drawContextData.clearImageColor.g    = 0.0;
  148.             pixmapDrawContextData.drawContextData.clearImageColor.b    = 0.0;
  149.             pixmapDrawContextData.drawContextData.paneState         = kQ3False;
  150.             pixmapDrawContextData.drawContextData.maskState         = kQ3False;
  151.             pixmapDrawContextData.drawContextData.doubleBufferState    = kQ3False;
  152.             
  153.             pixmapDrawContextData.pixmap.image        = GetPixBaseAddr(pixMapHandle);
  154.             pixmapDrawContextData.pixmap.width         = theConfig.width;
  155.             pixmapDrawContextData.pixmap.height        = theConfig.height;
  156.             pixmapDrawContextData.pixmap.rowBytes    = (*pixMapHandle)->rowBytes & 0x00003FFF;
  157.             pixmapDrawContextData.pixmap.pixelSize    = theActualConfig.frontBufferBestDepth;
  158.             pixmapDrawContextData.pixmap.bitOrder    = kQ3EndianBig;
  159.             pixmapDrawContextData.pixmap.byteOrder    = kQ3EndianBig;
  160.             
  161.             switch (pixmapDrawContextData.pixmap.pixelSize)
  162.             {
  163.                 case 16:
  164.                     pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB16;
  165.                 break;
  166.                 
  167.                 case 32:
  168.                     pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB32;
  169.                 break;
  170.                 
  171.                 default:
  172.                     assert(0);
  173.             }
  174.             
  175.             gDisplayDrawContext = Q3PixmapDrawContext_New(&pixmapDrawContextData);
  176.         }
  177.         #else
  178.         {
  179.             TQ3MacDrawContextData            macDrawContextData;
  180.             
  181.             // Create the draw context
  182.             macDrawContextData.drawContextData.clearImageMethod        = kQ3ClearMethodWithColor;
  183.             macDrawContextData.drawContextData.clearImageColor.a    = 1.0;
  184.             macDrawContextData.drawContextData.clearImageColor.r    = 0.0;
  185.             macDrawContextData.drawContextData.clearImageColor.g    = 0.0;
  186.             macDrawContextData.drawContextData.clearImageColor.b    = 0.0;
  187.             macDrawContextData.drawContextData.maskState            = kQ3False;
  188.             macDrawContextData.drawContextData.paneState            = kQ3False;
  189.             macDrawContextData.drawContextData.doubleBufferState    = kQ3False;
  190.             macDrawContextData.library                                = kQ3Mac2DLibraryNone;
  191.             macDrawContextData.viewPort                                = NULL;
  192.             macDrawContextData.grafPort                                = NULL;
  193.             
  194.             GetDisplayBackBuffer( gDisplayObject, &macDrawContextData.window );
  195.         
  196.             gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
  197.         }
  198.         #endif
  199.     }
  200.     #else
  201.     {
  202.         TQ3MacDrawContextData            macDrawContextData;
  203.         
  204.         // Create the window
  205.         gDisplayWindow = GetNewCWindow(kWindID_Display, NULL, (WindowPtr)(-1));
  206.         
  207.         // Create the draw context
  208.         macDrawContextData.drawContextData.clearImageMethod        = kQ3ClearMethodWithColor;
  209.         macDrawContextData.drawContextData.clearImageColor.a    = 1.0;
  210.         macDrawContextData.drawContextData.clearImageColor.r    = 0.0;
  211.         macDrawContextData.drawContextData.clearImageColor.g    = 0.0;
  212.         macDrawContextData.drawContextData.clearImageColor.b    = 0.0;
  213.         macDrawContextData.drawContextData.maskState            = kQ3False;
  214.         macDrawContextData.library                                = kQ3Mac2DLibraryNone;
  215.         macDrawContextData.drawContextData.paneState            = kQ3True;
  216.         macDrawContextData.drawContextData.doubleBufferState    = kQ3True;
  217.         macDrawContextData.window                                = (CGrafPtr) gDisplayWindow;
  218.         
  219.         Display_GetImageArea(&macDrawContextData.drawContextData.pane);
  220.     
  221.         gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
  222.     }
  223.     #endif
  224.     
  225.     Q3View_SetDrawContext(gDisplayView, gDisplayDrawContext);
  226.     
  227.     // Create the renderer
  228.     #if 1
  229.         gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  230.         Q3InteractiveRenderer_SetDoubleBufferBypass(gDisplayRenderer, kQ3True);
  231.     #else
  232.         gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireframe);
  233.     #endif
  234.     
  235.     Q3View_SetRenderer(gDisplayView, gDisplayRenderer);
  236.     
  237.     // Create the camera
  238.     viewAngleCameraData.cameraData.placement.cameraLocation.x    = 0.0;
  239.     viewAngleCameraData.cameraData.placement.cameraLocation.y    = 0.0;
  240.     viewAngleCameraData.cameraData.placement.cameraLocation.z    = 0.0;
  241.     viewAngleCameraData.cameraData.placement.pointOfInterest.x    = 1.0;
  242.     viewAngleCameraData.cameraData.placement.pointOfInterest.y    = 0.0;
  243.     viewAngleCameraData.cameraData.placement.pointOfInterest.z    = 0.0;
  244.     viewAngleCameraData.cameraData.placement.upVector.x            = 0.0;
  245.     viewAngleCameraData.cameraData.placement.upVector.y            = 1.0;
  246.     viewAngleCameraData.cameraData.placement.upVector.z            = 0.0;
  247.     viewAngleCameraData.cameraData.range.hither                    = 0.2;
  248.     viewAngleCameraData.cameraData.range.yon                    = 200.0;
  249.     viewAngleCameraData.cameraData.viewPort.origin.x            = -1.0;
  250.     viewAngleCameraData.cameraData.viewPort.origin.y            = 1.0;
  251.     viewAngleCameraData.cameraData.viewPort.width                = 2.0;
  252.     viewAngleCameraData.cameraData.viewPort.height                = 2.0;
  253.     viewAngleCameraData.fov                                        = 1.2;
  254.     viewAngleCameraData.aspectRatioXToY                            = Display_GetImageAspectRatio();
  255.  
  256.     gDisplayCamera = Q3ViewAngleAspectCamera_New(&viewAngleCameraData);
  257.     
  258.     Q3View_SetCamera(gDisplayView, gDisplayCamera);
  259.     
  260.     // Create the light group
  261.     gDisplayLightGroup = Q3LightGroup_New();
  262.     Q3View_SetLightGroup(gDisplayView, gDisplayLightGroup);
  263.     
  264.     // Create the point light
  265.     pointLightData.lightData.isOn        = kQ3True;
  266.     pointLightData.lightData.brightness    = 5.0;
  267.     pointLightData.lightData.color        = white;
  268.     pointLightData.castsShadows            = kQ3True;
  269.     pointLightData.attenuation            = kQ3AttenuationTypeInverseDistance;
  270.     pointLightData.location.x            = 0.0;
  271.     pointLightData.location.y            = 0.0;
  272.     pointLightData.location.z            = 0.0;
  273.     
  274.     gDisplayPointLight = Q3PointLight_New(&pointLightData);
  275.     
  276.     Q3Group_AddObject(gDisplayLightGroup, gDisplayPointLight);
  277.     
  278.     // Create the illumination shader
  279.     #if 1
  280.         gDisplayIllumination = Q3PhongIllumination_New();
  281.     #else
  282.         gDisplayIllumination = Q3LambertIllumination_New();
  283.     #endif
  284. }
  285.  
  286.  
  287. /* =============================================================================
  288.  *        Display_Exit (external)
  289.  *
  290.  *    Takes down the window, disposes of the QD3D stuff.
  291.  * ========================================================================== */
  292. void Display_Exit(
  293.     void)
  294. {
  295.     if (gDisplayHasRendered)
  296.     {
  297.         Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
  298.     }
  299.     
  300.     #if USE_DRAW_SPROCKET
  301.         if( gDisplayObject != NULL )
  302.         {
  303.             FadeDisplayGamma( NULL, kSmoothFadeOut, NULL );
  304.             SetDisplayPlayState( gDisplayObject, kDisplayPlayStateInactive );
  305.             FadeDisplayGamma( NULL, kSmoothFadeIn, NULL );
  306.             DisposeDisplay( gDisplayObject );
  307.             gDisplayObject = NULL;
  308.         }
  309.     #else
  310.         if (gDisplayWindow != NULL)
  311.         {
  312.             DisposeWindow(gDisplayWindow);
  313.             gDisplayWindow = NULL;
  314.         }
  315.     #endif
  316.     
  317.     if (gDisplayView != NULL)
  318.     {
  319.         Q3Object_Dispose(gDisplayView);
  320.         gDisplayView = NULL;
  321.     }
  322.     
  323.     if (gDisplayDrawContext != NULL)
  324.     {
  325.         Q3Object_Dispose(gDisplayDrawContext);
  326.         gDisplayDrawContext = NULL;
  327.     }
  328.     
  329.     if (gDisplayRenderer != NULL)
  330.     {
  331.         Q3Object_Dispose(gDisplayRenderer);
  332.         gDisplayRenderer = NULL;
  333.     }
  334.     
  335.     if (gDisplayCamera != NULL)
  336.     {
  337.         Q3Object_Dispose(gDisplayCamera);
  338.         gDisplayCamera = NULL;
  339.     }
  340.     
  341.     if (gDisplayLightGroup != NULL)
  342.     {
  343.         Q3Object_Dispose(gDisplayLightGroup);
  344.         gDisplayLightGroup = NULL;
  345.     }
  346.     
  347.     if (gDisplayAmbientLight != NULL)
  348.     {
  349.         Q3Object_Dispose(gDisplayAmbientLight);
  350.         gDisplayAmbientLight = NULL;
  351.     }
  352.     
  353.     if (gDisplayDirectionalLight != NULL)
  354.     {
  355.         Q3Object_Dispose(gDisplayDirectionalLight);
  356.         gDisplayDirectionalLight = NULL;
  357.     }
  358.     
  359.     if (gDisplayPointLight != NULL)
  360.     {
  361.         Q3Object_Dispose(gDisplayPointLight);
  362.         gDisplayPointLight = NULL;
  363.     }
  364.     
  365.     if (gDisplayIllumination != NULL)
  366.     {
  367.         Q3Object_Dispose(gDisplayIllumination);
  368.         gDisplayIllumination = NULL;
  369.     }
  370. }
  371.  
  372.  
  373. /* =============================================================================
  374.  *        Display_Activate (external)
  375.  *
  376.  *    Handles activation and deactivation.
  377.  * ========================================================================== */
  378. void Display_Activate(
  379.     Boolean            inActivate)
  380. {
  381.     if (gDisplayActive != inActivate)
  382.     {
  383.         gDisplayActive = inActivate;
  384.         
  385.         if (gDisplayHasRendered)
  386.         {
  387.             Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
  388.         }
  389.         
  390.         Display_DrawGrow();
  391.     }
  392. }
  393.  
  394.  
  395. /* =============================================================================
  396.  *        Display_IsActive (external)
  397.  *
  398.  *    Returns true if the game is active.
  399.  * ========================================================================== */
  400. Boolean Display_IsActive(
  401.     void)
  402. {
  403.     #if USE_DRAW_SPROCKET
  404.         return true;
  405.     #else
  406.         return gDisplayActive;
  407.     #endif
  408. }
  409.  
  410.  
  411. /* =============================================================================
  412.  *        Display_DrawGrow (external)
  413.  *
  414.  *    Draws the grow box.
  415.  * ========================================================================== */
  416. void Display_DrawGrow(
  417.     void)
  418. {
  419. #if !USE_DRAW_SPROCKET
  420.     Rect                bounds;
  421.     
  422.     SetPort(gDisplayWindow);
  423.     
  424.     // Erase the horizontal part
  425.     bounds = gDisplayWindow->portRect;
  426.     bounds.top = bounds.bottom-15;
  427.     
  428.     EraseRect(&bounds);
  429.     
  430.     // Draw the grow box, but only the horizontal scroll stuff
  431.     ClipRect(&bounds);
  432.     DrawGrowIcon(gDisplayWindow);
  433.     ClipRect(&gDisplayWindow->portRect);
  434. #endif
  435. }
  436.  
  437.  
  438. /* =============================================================================
  439.  *        Display_DrawImage (external)
  440.  *
  441.  *    Draws the 3D part of the window.
  442.  * ========================================================================== */
  443. void Display_DrawImage(
  444.     void)
  445. {
  446. #if USE_DRAW_SPROCKET
  447.     {
  448.         GWorldPtr theGWorld;
  449.         
  450.         GetDisplayBackBuffer( gDisplayObject, &theGWorld );
  451.         Q3MacDrawContext_SetWindow( gDisplayDrawContext, theGWorld );
  452.     }
  453. #endif
  454.  
  455.     Q3View_StartRendering(gDisplayView);
  456.     do
  457.     {
  458.         // Set up the rendering state
  459.         Q3InterpolationStyle_Submit(kQ3InterpolationStyleVertex, gDisplayView);
  460.         Q3BackfacingStyle_Submit(kQ3BackfacingStyleFlip, gDisplayView);
  461.         Q3FillStyle_Submit(kQ3FillStyleFilled, gDisplayView);
  462.         Q3Object_Submit(gDisplayIllumination, gDisplayView);
  463.         
  464.         // Draw the game contents
  465.         Game_Submit(gDisplayView);
  466.     }
  467.     while (Q3View_EndRendering(gDisplayView) == kQ3ViewStatusRetraverse);
  468.     
  469.     gDisplayHasRendered = true;
  470.  
  471. #if USE_DRAW_SPROCKET
  472.     SwapDisplayBuffers( gDisplayObject, Display_IsBusy, 0 );
  473. #endif
  474. }
  475.  
  476.  
  477. /* =============================================================================
  478.  *        Display_IsBusy (internal)
  479.  *
  480.  *    Called by SwapDisplayBuffers (or a VBL task that it kicks off) to determine
  481.  *    if the back buffer is finished rendering.  Since QD3D can render
  482.  *    asynchronously through hardware, we have to let it finish.  Unfortunately,
  483.  *    the only way to do this is to hang here with a renderer Sync call.
  484.  * ========================================================================== */
  485. #if USE_DRAW_SPROCKET
  486.     Boolean Display_IsBusy(
  487.         DisplayObject        inDisplayObject,
  488.         UInt32                inContext)
  489.     {
  490.         Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
  491.         return false;
  492.     }
  493. #endif
  494.  
  495.  
  496. /* =============================================================================
  497.  *        Display_Resize (external)
  498.  *
  499.  *    Called after the window has changed size.
  500.  * ========================================================================== */
  501. void Display_Resize(
  502.     void)
  503. {
  504. #if !USE_DRAW_SPROCKET
  505.     TQ3Area                    imageArea;
  506.     
  507.     // Reset the clip
  508.     ClipRect(&gDisplayWindow->portRect);
  509.     
  510.     // Change the draw context
  511.     Display_GetImageArea(&imageArea);
  512.     Q3DrawContext_SetPane(gDisplayDrawContext, &imageArea);
  513.     
  514.     // Change the camera aspect ratio
  515.     Q3ViewAngleAspectCamera_SetAspectRatio(gDisplayCamera, Display_GetImageAspectRatio());
  516. #endif
  517. }
  518.  
  519.  
  520. /* =============================================================================
  521.  *        Display_GetWindow (external)
  522.  *
  523.  *    Returns our window pointer.
  524.  * ========================================================================== */
  525. WindowPtr Display_GetWindow(
  526.     void)
  527. {
  528. #if USE_DRAW_SPROCKET
  529.     return NULL;
  530. #else
  531.     return gDisplayWindow;
  532. #endif
  533. }
  534.  
  535.  
  536. /* =============================================================================
  537.  *        Display_SetViewerPosition (external)
  538.  *
  539.  *    Moves the camera and point light based on the given info.
  540.  * ========================================================================== */
  541. void Display_SetViewerPosition(
  542.     const TQ3Point3D*        inPosition,
  543.     const TQ3Vector3D*        inDirection,
  544.     const TQ3Vector3D*        inUp)
  545. {
  546.     TQ3CameraPlacement        placement;
  547.     
  548.     assert(inPosition != NULL);
  549.     assert(inDirection != NULL);
  550.     assert(inUp != NULL);
  551.     
  552.     // Move the camera
  553.     placement.cameraLocation    = *inPosition;
  554.     placement.upVector            = *inUp;
  555.     
  556.     Q3Point3D_Vector3D_Add(inPosition, inDirection, &placement.pointOfInterest);
  557.     
  558.     Q3Camera_SetPlacement(gDisplayCamera, &placement);
  559.     
  560.     // Move the point light
  561.     Q3PointLight_SetLocation(gDisplayPointLight, inPosition);
  562. }
  563.  
  564.  
  565. /* =============================================================================
  566.  *        Display_GetViewerPosition (external)
  567.  *
  568.  *    Returns the current camera position.
  569.  * ========================================================================== */
  570. void Display_GetViewerPosition(
  571.     TQ3Point3D*                outPosition,
  572.     TQ3Vector3D*            outDirection,
  573.     TQ3Vector3D*            outUp)
  574. {
  575.     TQ3CameraPlacement        placement;
  576.     
  577.     assert(outPosition != NULL);
  578.     assert(outDirection != NULL);
  579.     assert(outUp != NULL);
  580.     
  581.     Q3Camera_GetPlacement(gDisplayCamera, &placement);
  582.     
  583.     *outPosition = placement.cameraLocation;
  584.     *outUp = placement.upVector;
  585.     
  586.     Q3Point3D_Subtract(
  587.             &placement.pointOfInterest,
  588.             &placement.cameraLocation,
  589.             outDirection);
  590. }
  591.  
  592.  
  593. /* =============================================================================
  594.  *        Display_GetImageArea (internal)
  595.  *
  596.  *    Sets outArea to the area occupied by the 3D image part of the window.
  597.  * ========================================================================== */
  598. void Display_GetImageArea(
  599.     TQ3Area*                outArea)
  600. {
  601.     assert(outArea != NULL);
  602.  
  603. #if USE_DRAW_SPROCKET
  604.     {
  605.         DisplayConfig theConfig;
  606.         
  607.         GetDisplayConfig( gDisplayObject, &theConfig );
  608.         
  609.         outArea->min.x = 0;
  610.         outArea->max.x = theConfig.width;
  611.         outArea->min.y = 0;
  612.         outArea->max.y = theConfig.height;
  613.     }
  614. #else    
  615.     outArea->min.x = gDisplayWindow->portRect.left;
  616.     outArea->max.x = gDisplayWindow->portRect.right;
  617.     outArea->min.y = gDisplayWindow->portRect.top;
  618.     outArea->max.y = gDisplayWindow->portRect.bottom-15;
  619. #endif
  620. }
  621.  
  622.  
  623. /* =============================================================================
  624.  *        Display_GetImageAspectRatio (internal)
  625.  *
  626.  *    Returns the aspect ratio of the area occupied by the 3D image part of the
  627.  *    window.
  628.  * ========================================================================== */
  629. float Display_GetImageAspectRatio(
  630.     void)
  631. {
  632.     TQ3Area                    imageArea;
  633.     
  634.     Display_GetImageArea(&imageArea);
  635.     
  636.     return (imageArea.max.x-imageArea.min.x) / (imageArea.max.y-imageArea.min.y);
  637. }
  638.